home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 6 / QRZ Ham Radio Callsign Database - Volume 6.iso / pc / files / amiga / asrc29p.lha / ppppap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-29  |  21.1 KB  |  953 lines

  1. /*
  2.  *  PPPPAP.C    -- Password Authenticate Protocol for PPP
  3.  *
  4.  *    12-89    -- Katie Stevens (dkstevens@ucdavis.edu)
  5.  *           UC Davis, Computing Services
  6.  *    PPP.09    05-90    [ks] add authentication phase
  7.  *    PPP.10    06-90    [ks] improve keybd input of PAP password
  8.  *                 make ppp open/close/reset work properly
  9.  *    PPP.14    08-90    [ks] change PAP to PPP for consistency with RFC1172
  10.  *    PPP.15    09-90    [ks] update to KA9Q NOS v900828
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include "global.h"
  15. #include "files.h"
  16. #include "mbuf.h"
  17. #include "proc.h"
  18. #include "iface.h"
  19. #include "ppp.h"
  20. #include "slip.h"
  21. #include "session.h"
  22. #include "ftpserv.h"
  23.  
  24. /* Counter for PPP id field */
  25. extern unsigned char pppid;
  26.  
  27. /* PPP tracing */
  28. extern int ppptrace;
  29.  
  30. static void pap_open __ARGS((struct slip *sp));
  31.  
  32. static int pap_authen __ARGS((char *peerid, char *pass));
  33. void pap_input __ARGS((int mustask, void *v1, void *v2));
  34. static void pap_pwdlookup __ARGS((struct lcpctl *lcpiop));
  35.  
  36. static int pap_sendreq __ARGS((struct slip *sp));
  37. static struct mbuf *pap_makereq __ARGS((struct lcpctl *lcpiop));
  38.  
  39. static void pap_rcvack __ARGS((struct slip *sp, struct cnfhdr *rcnf,
  40.             struct mbuf *data));
  41. static void pap_rcvnak __ARGS((struct slip *sp, struct cnfhdr *rcnf,
  42.             struct mbuf *data));
  43. static void pap_rcvreq __ARGS((struct slip *sp, struct cnfhdr *rcnf,
  44.             struct mbuf *data));
  45. static void pap_shutdown __ARGS((struct slip *sp));
  46.  
  47. static int pap_chkack __ARGS((struct slip *sp, struct cnfhdr *ackcnf,
  48.             struct mbuf *data));
  49. static int pap_chknak __ARGS((struct slip *sp, struct cnfhdr *nakcnf,
  50.             struct mbuf *data));
  51. static void pap_chkreq __ARGS((struct slip *sp, struct cnfhdr *reqcnf,
  52.             struct mbuf *data));
  53.  
  54. static void pap_timeout __ARGS((void *vp));
  55. static void pap_timer __ARGS((struct slip *sp));
  56.  
  57. static int pap_sendreply __ARGS((struct slip *sp, char code,
  58.             unsigned char id, struct mbuf *data));
  59.  
  60. /* Possible PAP states */
  61. static char *PAPStates[] = {
  62.     "Closed",
  63.     "Listen",
  64.     "Req Sent",
  65.     "Req Rcvd",
  66.     "Open",
  67. };
  68.  
  69. /* Possible PAP packet types */
  70. static char *PAPCodes[] = {
  71.     NULLCHAR,
  72.     "Auth Req",
  73.     "Auth Ack",
  74.     "Auth Nak",
  75. };
  76.  
  77. /****************************************************************************/
  78.  
  79. /* Initialize Password Auth Protocol state machine for config exchange */
  80. int
  81. pap_start(sp)
  82. struct slip *sp;
  83. {
  84.     struct pppctl *pppiop;
  85.     struct lcpctl *lcpiop;
  86.  
  87.     if (ppptrace > 5)
  88.         mainlog(-1, "pap_start()");
  89.  
  90.     pppiop = sp->pppio;
  91.     lcpiop = &(pppiop->lcpio);
  92.  
  93.     /* Ready for PAP phase */
  94.     pppiop->state = PPP_PAP;
  95.     pap_reset(pppiop);
  96.  
  97.     /* Just finished LCP negotiation; prepare for PAP negotiation */
  98.     if (lcpiop->lclparm.auth_type == PAP_AUTH_TYPE) {
  99.         /* We asked remote to send AUTH_REQ; wait for that packet */
  100.         lcpiop->pap_state = PAP_LISTEN;
  101.         return 0;
  102.     }
  103.  
  104.     /* Remote host asked us to send AUTH_REQ */
  105.     lcpiop->pap_state = PAP_CLOSED;
  106.     /* We need to send AUTH_REQ to remote host */
  107.     /* Get the peer ID and password we will send */
  108.     if ((lcpiop->pap_user == NULLCHAR)||(lcpiop->pap_pass == NULLCHAR)) {
  109.         pap_getpass(sp,0);
  110.         pwait(&(lcpiop->pap_user));
  111.         if ((lcpiop->pap_user == NULLCHAR) ||
  112.             (lcpiop->pap_pass == NULLCHAR))
  113.             return -1;
  114.     }
  115.     return(pap_sendreq(sp));
  116. }
  117.  
  118. /*******************************************/
  119.  
  120. /* Initialize our PAP configuration options */
  121. void
  122. pap_init(sp)
  123. struct slip *sp;
  124. {
  125.     struct pppctl *pppiop;
  126.     struct lcpctl *lcpiop;
  127.  
  128.     if (ppptrace > 5)
  129.         mainlog(-1, "pap_init()");
  130.  
  131.     pppiop = sp->pppio;
  132.     lcpiop = &(pppiop->lcpio);
  133.  
  134.     /* PAP layer closed; dont know local peerID/password values */
  135.     lcpiop->pap_state = PAP_CLOSED;
  136.     lcpiop->pap_user = NULLCHAR;
  137.     lcpiop->pap_pass = NULLCHAR;
  138.     return;
  139. }
  140.  
  141. /* IP Control configuration negotiation complete */
  142. static void
  143. pap_open(sp)
  144. struct slip *sp;
  145. {
  146.     struct pppctl *pppiop;
  147.     struct lcpctl *lcpiop;
  148.  
  149.     pppiop = sp->pppio;
  150.     lcpiop = &(pppiop->lcpio);
  151.  
  152.     /* Mark PAP as completed */
  153.     if (ppptrace)
  154.         mainlog(-1,"%s: PPP/PAP: peer ID verified %s",
  155.             sp->iface->name,lcpiop->pap_user);
  156.     lcpiop->pap_state = PAP_OPEN;
  157.  
  158.     /* Ready for IPCP negotiation phase */
  159.     ipcp_start(sp);
  160.     return;
  161. }
  162.  
  163. /* Reset PAP configuration options for initial request */
  164. int
  165. pap_reset(pppiop)
  166. struct pppctl *pppiop;
  167. {
  168.     struct lcpctl *lcpiop;
  169.  
  170.     if (ppptrace > 5)
  171.         mainlog(-1, "pap_reset()");
  172.  
  173.     lcpiop = &(pppiop->lcpio);
  174.     lcpiop->pap_state = PAP_CLOSED;
  175.     lcpiop->ack_retry = 0;
  176.  
  177.     return 0;
  178. }
  179.  
  180. /*******************************************/
  181.  
  182. /* Verify peer ID and password sent by remote host with PAP AUTH_REQ */
  183. static int
  184. pap_authen(peerid,pass)
  185. char *peerid;
  186. char *pass;
  187. {
  188.     int privs;
  189.     char *path;
  190.     int anony = 0;
  191.  
  192.     /* Use same login as FTP server */
  193.     path = mallocw(128);
  194.     privs = userlogin(peerid,pass,&path,128,&anony);
  195.     free(path);
  196.  
  197.     /* Check privs for this peer ID */
  198.     if (privs == -1) {
  199.         if (ppptrace > 2)
  200.             mainlog(-1,
  201.                "PAP peerID/password incorrect or not found: %s",
  202.                peerid);
  203.         return -1;
  204.     }
  205.     if ((privs & PPP_ACCESS_PRIV) == 0) {
  206.         if (ppptrace > 2)
  207.             mainlog(-1,"PAP no permission for PPP access: %s",peerid);
  208.         return -1;
  209.     }
  210.     return 0;
  211. }
  212.  
  213. /* Get peerID and password to send to remote host with PAP AUTH_REQ */
  214. int
  215. pap_getpass(sp,mustask)
  216. struct slip *sp;
  217. int mustask;
  218. {
  219.     struct pppctl *pppiop;
  220.     struct lcpctl *lcpiop;
  221.  
  222.     pppiop = sp->pppio;
  223.     lcpiop = &(pppiop->lcpio);
  224.     if (mustask) {
  225.         if (lcpiop->pap_user != NULLCHAR) {
  226.             free(lcpiop->pap_user);
  227.             lcpiop->pap_user = NULLCHAR;
  228.         }
  229.         if (lcpiop->pap_pass != NULLCHAR) {
  230.             free(lcpiop->pap_pass);
  231.             lcpiop->pap_pass = NULLCHAR;
  232.         }
  233.     } else if ((lcpiop->pap_user != NULLCHAR)
  234.             &&(lcpiop->pap_pass == NULLCHAR)) {
  235.         pap_pwdlookup(lcpiop);
  236.     }
  237.     if ((lcpiop->pap_user == NULLCHAR)||(lcpiop->pap_pass == NULLCHAR)) {
  238.         newproc("PAP Input",256,pap_input,mustask,
  239.              (void *)sp->iface,
  240.              (void *)lcpiop);
  241.     }
  242.     return 0;
  243. }
  244.  
  245. void
  246. pap_input(mustask, v1, v2)
  247. int mustask;
  248. void *v1;
  249. void *v2;
  250. {
  251.     struct iface *iface;
  252.     struct lcpctl *lcpiop;
  253.     char buf[21];
  254.     struct session *sp;
  255.  
  256.     iface = (struct iface *)v1;
  257.     lcpiop = (struct lcpctl *)v2;
  258.  
  259.     /* Allocate a session control block */
  260.     if((sp = newsession("PPP/PAP Auth",PPPPASS,0)) == NULLSESSION){
  261.         tprintf("Too many sessions\n");
  262.         return;
  263.     }
  264.  
  265.     if (mustask)
  266.         tprintf("\n%s: PPP/PAP Password Authentication Failed; enter peer ID and password again\n",
  267.             iface->name);
  268.     else
  269.         tprintf("\n%s: PPP/PAP Password Authentication Required\n",
  270.             iface->name);
  271.     tprintf("%s: PPP/PAP  Peer ID: ",iface->name);
  272.     usflush(sp->output);
  273.  
  274.     /* Only ask for the peer ID if it is unknown */
  275.     if (lcpiop->pap_user == NULLCHAR) {
  276.         recvline(sp->input,buf,20);
  277.         /* Send the command only if the user response
  278.          * was non-null
  279.          */
  280.         if (buf[0] == '\n')
  281.             lcpiop->pap_user = NULLCHAR;
  282.         else {
  283.             rip(buf);
  284.             lcpiop->pap_user = mallocw(strlen(buf)+1);
  285.             strcpy(lcpiop->pap_user,buf);
  286.         }
  287.     } else {
  288.         tprintf("%s\n",lcpiop->pap_user);
  289.     }
  290.  
  291.     /* Always ask for the password */
  292.     /* turn off echo */
  293.     sp->ttystate.echo = 0;
  294.     tprintf("%s: PPP/PAP Password: ",iface->name);
  295.     usflush(sp->output);
  296.     recvline(sp->input,buf,20);
  297.     tprintf("\n");
  298.     /* Turn echo back on */
  299.     sp->ttystate.echo = 1;
  300.     /* Save the password only if the user response was non-null */
  301.     if (buf[0] == '\n')
  302.         lcpiop->pap_pass = NULLCHAR;
  303.     else {
  304.         rip(buf);
  305.         lcpiop->pap_pass = mallocw(strlen(buf)+1);
  306.         strcpy(lcpiop->pap_pass,buf);
  307.     }
  308.  
  309.     if (sp != NULLSESSION)
  310.         freesession(sp);
  311.  
  312.     psignal(&(lcpiop->pap_user),0);
  313.     return;    
  314. }
  315.  
  316. /* Check the FTP userfile for this peer ID; get password if available */
  317. static void
  318. pap_pwdlookup(lcpiop)
  319. struct lcpctl *lcpiop;
  320. {
  321.     char *buf;
  322.     char *cp, *cp1;
  323.     char *svp;
  324.     FILE *fp;
  325.     int perm;
  326.  
  327.     if((fp = fopen(Userfile,READ_TEXT)) == NULLFILE)
  328.         /* Userfile doesn't exist */
  329.         return;
  330.  
  331.     /* Locate user name in password file */
  332.     buf = mallocw(128);
  333.     while(fgets(buf,128,fp),!feof(fp)){
  334.         if(buf[0] == '#')
  335.             continue;    /* Comment */
  336.         if((cp = strchr(buf,' ')) == NULLCHAR)
  337.             /* Bogus entry */
  338.             continue;
  339.         *cp++ = '\0';        /* Now points to password */
  340.         svp = cp;        /* Save ptr to password */
  341.         if(stricmp(lcpiop->pap_user,buf) == 0)
  342.             break;        /* Found peer ID */
  343.     }
  344.     if(feof(fp)){
  345.         /* Peer ID not found in file */
  346.         fclose(fp);
  347.         free(buf);
  348.         return;
  349.     }
  350.     fclose(fp);
  351.     /* Look for space after password field in file */
  352.     if((cp1 = strchr(cp,' ')) == NULLCHAR) {
  353.         /* Invalid file entry */
  354.         free(buf);
  355.         return;
  356.     }
  357.     *cp1++ = '\0';    /* Now points to path field */
  358.     if((cp = strchr(cp1,' ')) == NULLCHAR) {
  359.         /* Permission field missing */
  360.         free(buf);
  361.         return;
  362.     }
  363.     *cp++ = '\0';    /* now points to permission field */
  364.     perm = atoi(cp);
  365.  
  366.     /* Check permissions for this peer ID */
  367.     if ((perm & PPP_PWD_LOOKUP) == 0) {
  368.         /* Not in ftpuser file for password lookup */
  369.         free(buf);
  370.         return;
  371.     }
  372.  
  373.     /* Save the password from this userfile record */
  374.     lcpiop->pap_pass = malloc(strlen(svp)+1);
  375.     strcpy(lcpiop->pap_pass,svp);
  376.     return;
  377. }
  378.  
  379. /****************************************************************************/
  380.  
  381. /* Send our PAP configuration request */
  382. static int
  383. pap_sendreq(sp)
  384. struct slip *sp;
  385. {
  386.     struct pppctl *pppiop;
  387.     struct lcpctl *lcpiop;
  388.     struct mbuf *bp;
  389.  
  390.     if (ppptrace > 5)
  391.         mainlog(-1,"pap_sendreq()");
  392.  
  393.     pppiop = sp->pppio;
  394.     lcpiop = &(pppiop->lcpio);
  395.  
  396.     /* Get a packet with our configuration request */
  397.     bp = pap_makereq(lcpiop);
  398.  
  399.     /* Start timer against wait for reply to our config request */
  400.     pap_timer(sp);
  401.  
  402.     /* Send PAP configuration request to remote host */
  403.     pppiop->state = PPP_PAP;
  404.     if (lcpiop->pap_state != PAP_REQ_SENT)
  405.         lcpiop->pap_state = PAP_REQ_SENT;
  406.     return(pap_sendreply(sp, AUTH_REQ, 0, bp));
  407. }
  408.  
  409. /*******************************************/
  410.  
  411. static struct mbuf *
  412. pap_makereq(lcpiop)
  413. struct lcpctl *lcpiop;
  414. {
  415.     register unsigned char *cp;
  416.     struct mbuf *req_bp;
  417.     int len;
  418.  
  419.     if (ppptrace > 5)
  420.         mainlog(-1,"    pap_makereq()   peer ID: %s",lcpiop->pap_user);
  421.  
  422.     /* Get buffer for authenticate request packet */
  423.     len = strlen(lcpiop->pap_user)+strlen(lcpiop->pap_pass)+2;
  424.     if ((req_bp = alloc_mbuf(len)) == NULLBUF)
  425.         return NULLBUF;
  426.  
  427.     /* Load peer ID and password for authenticate packet */
  428.     cp = req_bp->data;
  429.     *cp++ = (char)strlen(lcpiop->pap_user);
  430.     memcpy(cp, lcpiop->pap_user, strlen(lcpiop->pap_user));
  431.     cp += strlen(lcpiop->pap_user);
  432.     *cp++ = (char)strlen(lcpiop->pap_pass);
  433.     memcpy(cp, lcpiop->pap_pass, strlen(lcpiop->pap_pass));
  434.     req_bp->cnt += len;
  435.  
  436.     /* Return our config request */
  437.     return(req_bp);
  438. }
  439.  
  440. /****************************************************************************/
  441.  
  442. /* Remote host ACKed our configuration request */
  443. static void
  444. pap_rcvack(sp, rcnf, data)
  445. struct slip *sp;
  446. struct cnfhdr *rcnf;
  447. struct mbuf *data;
  448. {
  449.     struct pppctl *pppiop;
  450.     struct lcpctl *lcpiop;
  451.  
  452.     if (ppptrace > 5)
  453.         mainlog(-1, "pap_rcvack()");
  454.  
  455.     pppiop = sp->pppio;
  456.     lcpiop = &(pppiop->lcpio);
  457.     stop_timer(&lcpiop->lcp_tm);
  458.  
  459.     switch(lcpiop->pap_state) {
  460.     case PAP_REQ_SENT:
  461.         /* Make sure ACK is proper */
  462.         if (pap_chkack(sp, rcnf, data) != -1) {
  463.             /* Remote host accepted our request */
  464.             pap_open(sp);
  465.             break;
  466.         }
  467.  
  468.         /* Still need to settle request from remote host */
  469.         pap_timer(sp);
  470.         break;
  471.  
  472.     case PAP_REQ_RCVD:
  473.     case PAP_CLOSED:
  474.     case PAP_LISTEN:
  475.     case PAP_OPEN:
  476.     default:
  477.         /* Confusion; shutdown the connection */
  478.         free_p(data);
  479.         pap_shutdown(sp);
  480.         break;
  481.     }
  482.     return;
  483. }
  484.  
  485. /* Remote host NAKed our configuration request */
  486. static void
  487. pap_rcvnak(sp, rcnf, data)
  488. struct slip *sp;
  489. struct cnfhdr *rcnf;
  490. struct mbuf *data;
  491. {
  492.     struct pppctl *pppiop;
  493.     struct lcpctl *lcpiop;
  494.  
  495.     if (ppptrace > 5)
  496.         mainlog(-1, "pap_rcvnak()");
  497.  
  498.     pppiop = sp->pppio;
  499.     lcpiop = &(pppiop->lcpio);
  500.     stop_timer(&lcpiop->lcp_tm);
  501.  
  502.     switch(lcpiop->pap_state) {
  503.     case PAP_REQ_SENT:
  504.         /* Remote host NAKd our AUTH_REQ */
  505.         if (pap_chknak(sp, rcnf, data) == -1) {
  506.             /* Bad NAK packet */
  507.             /* Wait for another; resend request on timeout */
  508.             pap_timer(sp);
  509.             break;
  510.         }
  511.         /* Must have sent a bad peer ID or password */
  512.         /* Get the password again */
  513.         pap_getpass(sp,1);
  514.         pwait(&(lcpiop->pap_user));
  515.         if (lcpiop->pap_pass == NULLCHAR)
  516.             /* No password entered, close PPP link */
  517.             pap_shutdown(sp);
  518.         else
  519.             /* Send AUTH_REQ again with new password */
  520.             pap_sendreq(sp);
  521.         break;
  522.     case PAP_REQ_RCVD:
  523.     case PAP_OPEN:
  524.     case PAP_CLOSED:
  525.     case PAP_LISTEN:
  526.     default:
  527.         /* Confusion; shutdown the connection */
  528.         free_p(data);
  529.         pap_shutdown(sp);
  530.         break;
  531.     }
  532.     return;
  533. }
  534.  
  535. /* Process configuration request sent by remote host */
  536. static void
  537. pap_rcvreq(sp, rcnf, data)
  538. struct slip *sp;
  539. struct cnfhdr *rcnf;
  540. struct mbuf *data;
  541. {
  542.     struct pppctl *pppiop;
  543.     struct lcpctl *lcpiop;
  544.  
  545.     if (ppptrace > 5)
  546.         mainlog(-1, "pap_rcvreq()");
  547.  
  548.     pppiop = sp->pppio;
  549.     lcpiop = &(pppiop->lcpio);
  550.  
  551.     switch(lcpiop->pap_state) {
  552.     case PAP_LISTEN:    /* Normal event */
  553.     case PAP_REQ_RCVD:    /* Normal event */
  554.         /* Evaluate configuration request from remote host */
  555.         pap_chkreq(sp, rcnf, data);
  556.         break;
  557.  
  558.     case PAP_CLOSED:
  559.     case PAP_REQ_SENT:
  560.     case PAP_OPEN:
  561.     default:
  562.         /* We are closed; dont accept any connections */
  563.         free_p(data);
  564.         pap_shutdown(sp);
  565.         break;
  566.     }
  567.     return;
  568. }
  569.  
  570. /* PAP failure, abandon PAP attempt; shutdown LCP layer */
  571. static void
  572. pap_shutdown(sp)
  573. struct slip *sp;
  574. {
  575.     struct pppctl *pppiop;
  576.  
  577.     if (ppptrace > 5)
  578.         mainlog(-1, "pap_shutdown()");
  579.  
  580.     pppiop = sp->pppio;
  581.  
  582.     if (ppptrace > 1)
  583.         mainlog(-1,"%s: PPP/PAP: Failed; close PPP connection",sp->iface->name);
  584.     pap_reset(pppiop);
  585.  
  586.     /* Shut the link down completely */
  587.     lcp_shutdown(sp);
  588.     return;
  589. }
  590.  
  591. /*******************************************/
  592.  
  593. /* Process configuration ACK send by remote host */
  594. static int
  595. pap_chkack(sp, ackcnf, data)
  596. struct slip *sp;
  597. struct cnfhdr *ackcnf;
  598. struct mbuf *data;
  599. {
  600.     int ackerr = 0;
  601.     struct pppctl *pppiop;
  602.     struct lcpctl *lcpiop;
  603.     char *pap_msg;
  604.     int len;
  605.  
  606.     if (ppptrace > 5)
  607.         mainlog(-1,"pap_chkack()");
  608.  
  609.     pppiop = sp->pppio;
  610.     lcpiop = &(pppiop->lcpio);
  611.  
  612.     /* PAP ID field must match last request we sent */
  613.     if (ackcnf->id != lcpiop->lastid) {
  614.         if (ppptrace > 5)
  615.             mainlog(-1,"improper PAP ACK; bad ID");
  616.         free_p(data);
  617.         return -1;
  618.     }
  619.  
  620.     if ((ppptrace > 1) && (len_p(data) != 0)) {
  621.         /* Log ASCII message from remote host, if any */
  622.         len = pullchar(&data);
  623.         pap_msg = mallocw(len+1);
  624.         len = dqdata(data,pap_msg,len);
  625.         pap_msg[len] = '\0';
  626.         mainlog(-1,"%s: PPP/PAP: ACK msg: %s",sp->iface->name,pap_msg);
  627.         free(pap_msg);
  628.     } else {
  629.         free_p(data);
  630.     }
  631.  
  632.     if (ackerr) {
  633.         /* Error in configuration ACK */
  634.         if (ppptrace > 5)
  635.             mainlog(-1,"improper PAP ACK");
  636.         return -1;
  637.     }
  638.  
  639.     /* ACK is acceptable */
  640.     if (ppptrace > 5)
  641.         mainlog(-1,"valid PAP ACK");
  642.     return 0;
  643. }
  644.  
  645. /* Process configuration NAK send by remote host */
  646. static int
  647. pap_chknak(sp, nakcnf, data)
  648. struct slip *sp;
  649. struct cnfhdr *nakcnf;
  650. struct mbuf *data;
  651. {
  652.     int nakerr = 0;
  653.     struct pppctl *pppiop;
  654.     struct lcpctl *lcpiop;
  655.     int len;
  656.     char *pap_msg;
  657.  
  658.     if (ppptrace > 5)
  659.         mainlog(-1,"pap_chknak()");
  660.  
  661.     pppiop = sp->pppio;
  662.     lcpiop = &(pppiop->lcpio);
  663.  
  664.     /* PAP ID field must match last request we sent */
  665.     if (nakcnf->id != lcpiop->lastid) {
  666.         if (ppptrace > 1)
  667.             mainlog(-1,"improper PAP NAK; bad ID");
  668.         free_p(data);
  669.         return -1;
  670.     }
  671.  
  672.     if ((ppptrace > 1) && (len_p(data) != 0)) {
  673.         /* Log ASCII message from remote host, if any */
  674.         len = pullchar(&data);
  675.         pap_msg = mallocw(len+1);
  676.         len = dqdata(data,pap_msg,len);
  677.         pap_msg[len] = '\0';
  678.         mainlog(-1,"%s: PPP/PAP: NAK msg: %s",sp->iface->name,pap_msg);
  679.         free(pap_msg);
  680.     } else {
  681.         free_p(data);
  682.     }
  683.  
  684.     if (nakerr) {
  685.         /* Error in configuration NAK */
  686.         if (ppptrace > 5)
  687.             mainlog(-1,"improper PAP NAK");
  688.         return -1;
  689.     }
  690.  
  691.     /* NAK packet was properly constructed */
  692.     if (ppptrace > 5)
  693.         mainlog(-1,"valid PAP NAK");
  694.     return 0;
  695. }
  696.  
  697. /* Check IP Control options requested by the remote host */
  698. static void
  699. pap_chkreq(sp, reqcnf, data)
  700. struct slip *sp;
  701. struct cnfhdr *reqcnf;
  702. struct mbuf *data;
  703. {
  704.     struct pppctl *pppiop;
  705.     struct lcpctl *lcpiop;
  706.     int ilen,ulen,plen;
  707.     char cnf_accept;            /* Overall reply to request */
  708.     struct mbuf *reply_bp;            /* Actual reply packet */
  709.     char userpass[48];            /* Storage for peerID/pass */
  710.     char *pap_msg;                /* Message for remote host */
  711.  
  712.     if (ppptrace > 5)
  713.         mainlog(-1, "pap_chkreq()");
  714.  
  715.     pppiop = sp->pppio;
  716.     lcpiop = &(pppiop->lcpio);
  717.     lcpiop->pap_state = PAP_REQ_RCVD;
  718.  
  719.     /* Make sure length in PAP config header is realistic */
  720.     ilen = len_p(data);
  721.     if (ilen < reqcnf->len)
  722.         reqcnf->len = ilen;
  723.  
  724.     /* Extract peerID/password sent by remote host */
  725.     dqdata(data,userpass,48);
  726.     ulen = (int)userpass[0];
  727.     if (ulen >= 48) {
  728.         strcpy(userpass,"foo");
  729.     } else {
  730.         ++ulen;
  731.         plen = (int)userpass[ulen];
  732.         userpass[ulen] = '\0';
  733.         ++ulen;
  734.         plen += ulen;
  735.         if (plen >= 48)
  736.             plen = 47;
  737.         userpass[plen] = '\0';
  738.     }
  739.     if (ppptrace > 5)
  740.         mainlog(-1,"PAP peer ID: %s",&(userpass[1]));
  741.  
  742.     /* Verify peerID/pass sent by remote host */
  743.     if (lcpiop->pap_user != NULLCHAR) {
  744.         free(lcpiop->pap_user);
  745.         lcpiop->pap_user = NULLCHAR;
  746.     }
  747.     if (pap_authen(&(userpass[1]),&(userpass[ulen])) == -1) {
  748.         cnf_accept = AUTH_NAK;
  749.         pap_msg = " Invalid peer ID or password";
  750.     } else {
  751.         cnf_accept = AUTH_ACK;
  752.         pap_msg = " Welcome to the Internet";
  753.         lcpiop->pap_user = mallocw(strlen(&(userpass[1]))+1);
  754.         strcpy(lcpiop->pap_user,&(userpass[1]));
  755.     }
  756.     ilen = strlen(pap_msg);
  757.     reply_bp = qdata(pap_msg,ilen);
  758.     reply_bp->data[0] = (char)(ilen - 1);
  759.  
  760.     /* Send ACK/NAK to remote host */
  761.     if (cnf_accept == AUTH_ACK) {
  762.         if (ppptrace > 1)
  763.             mainlog(-1, "%s: PPP/PAP: peerID (%s) from remote host has been verified",
  764.                 sp->iface->name,&(userpass[1]));
  765.  
  766.         /* Accept configuration requested by remote host */
  767.         pap_sendreply(sp, AUTH_ACK, reqcnf->id, reply_bp);
  768.         /* PPP data link now ready for next phase */
  769.         pap_open(sp);
  770.     } else {
  771.         /* NAK config request made by remote host */
  772.         if (ppptrace)
  773.             mainlog(-1,"%s: PPP/PAP: invalid peerID (%s) from remote host",
  774.                 sp->iface->name,&(userpass[1]));
  775.         pap_sendreply(sp, AUTH_NAK, reqcnf->id, reply_bp);
  776.         if (++lcpiop->ack_retry > PAP_FAIL_MAX) {
  777.             /* Shut the link down after too many failed auth */
  778.             if (ppptrace)
  779.                 mainlog(-1,"%s: PPP/PAP: Failed; too many failed attempts; close PPP link",
  780.                     sp->iface->name);
  781.             pap_shutdown(sp);
  782.         } else {
  783.             if (ppptrace > 1)
  784.                 mainlog(-1,"%s: PPP/PAP: not verified; wait for another attempt",
  785.                     sp->iface->name);
  786.         }
  787.     }
  788.     return;
  789. }
  790.  
  791. /****************************************************************************/
  792.  
  793. /* Timeout while waiting for reply from remote host */
  794. static void
  795. pap_timeout(vp)
  796. void *vp;
  797. {
  798.     struct slip *sp;
  799.     struct pppctl *pppiop;
  800.     struct lcpctl *lcpiop;
  801.  
  802.     if (ppptrace > 1)
  803.         mainlog(-1, "pap_timeout()");
  804.  
  805.     /* Load pointers to interface that timed-out */
  806.     sp = (struct slip *)vp;
  807.     pppiop = sp->pppio;
  808.     lcpiop = &(pppiop->lcpio);
  809.  
  810.     /* Attempt to get things going again */
  811.     switch(lcpiop->pap_state) {
  812.     case PAP_REQ_SENT:
  813.         /* Timeout waiting for ACK to our request */
  814.         if (++lcpiop->ack_retry > PAP_RETRY_MAX) {
  815.             /* Remote host doesnt seem to be listening */
  816.             pap_shutdown(sp);
  817.             break;
  818.         }
  819.         /* Resend the request */
  820.         pap_sendreq(sp);
  821.         break;
  822.  
  823.     case PAP_REQ_RCVD:
  824.     case PAP_CLOSED:
  825.     case PAP_LISTEN:
  826.     case PAP_OPEN:
  827.     default:
  828.         /* Confusion; shutdown the connection */
  829.         pap_shutdown(sp);
  830.         break;
  831.     }
  832.     return;
  833. }
  834.  
  835. /* Set a timer in case an expected event does not occur */
  836. static void
  837. pap_timer(sp)
  838. struct slip *sp;
  839. {
  840.     struct pppctl *pppiop;
  841.     struct lcpctl *lcpiop;
  842.     struct timer *t;
  843.  
  844.     if (ppptrace > 5)
  845.         mainlog(-1,"pap_timer()");
  846.  
  847.     pppiop = sp->pppio;
  848.     lcpiop = &(pppiop->lcpio);
  849.     t = &(lcpiop->lcp_tm);
  850.     t->func = (void (*)())pap_timeout;
  851.     t->arg = (void *)sp;
  852.     start_timer(t);
  853.     return;
  854. }
  855.  
  856. /****************************************************************************/
  857.  
  858. /* Send an PAP packet to the remote host */
  859. static int
  860. pap_sendreply(sp,code,id,data)
  861. struct slip *sp;
  862. char code;
  863. unsigned char id;
  864. struct mbuf *data;
  865. {
  866.     struct iface *iface;
  867.     struct cnfhdr hdr;
  868.  
  869.     /* Load PAP header values */
  870.     hdr.code = code;
  871.     switch(code) {
  872.     case AUTH_REQ:
  873.         /* Save ID field for match aginst replies from remote host */
  874.         sp->pppio->lcpio.lastid = pppid;
  875.         /* Use a unique ID field value */
  876.         hdr.id = pppid++;
  877.         break;
  878.  
  879.     case AUTH_ACK:
  880.     case AUTH_NAK:
  881.         /* Use ID sent by remote host */
  882.         hdr.id = id;
  883.         break;
  884.  
  885.     default:
  886.         /* Shouldnt happen */
  887.         if (ppptrace)
  888.             mainlog(-1, "%s: PPP/PAP: bogus code: %x\n",
  889.                 sp->iface->name, code);
  890.         return -1;
  891.     }
  892.     hdr.len = len_p(data) + CNF_HDRLEN;
  893.  
  894.     /* Prepend PAP header to packet data */
  895.     if ((data = htoncnf(&hdr,data)) == NULLBUF)
  896.         return -1;
  897.  
  898.     if (ppptrace > 1)
  899.         mainlog(-1, "%s: PPP/PAP Send: current state: %s   PAP option: %s  id: %d  len: %d",
  900.             sp->iface->name,
  901.             PAPStates[sp->pppio->lcpio.pap_state],
  902.             PAPCodes[code],hdr.id,hdr.len);
  903.  
  904.     /* Send PAP packet to remote host */
  905.     sp->pppio->sndpap++;
  906.     iface = sp->iface;
  907.     return( (*iface->output)
  908.         (iface, NULLCHAR, NULLCHAR, PPP_PAP_TYPE, data) );
  909. }
  910.  
  911. /* Process incoming PAP packet */
  912. void
  913. papproc(iface,bp)
  914. struct iface *iface;
  915. struct mbuf *bp;
  916. {
  917.     struct slip *sp;
  918.     struct cnfhdr hdr;
  919.  
  920.     sp = &Slip[iface->xdev];
  921.  
  922.     /* Extract PAP header */
  923.     ntohcnf(&hdr, &bp);
  924.     hdr.len -= CNF_HDRLEN;            /* Length includes envelope */
  925.     trim_mbuf(&bp, hdr.len);        /* Trim off FCS bytes */
  926.  
  927.     if (ppptrace > 1)
  928.         mainlog(-1,    "%s: PPP/PAP Recv: current state: %s   PAP option: %s    id: %d   len: %d",
  929.             iface->name,
  930.             PAPStates[sp->pppio->lcpio.pap_state],
  931.             PAPCodes[hdr.code], hdr.id, hdr.len);
  932.  
  933.     /* Process PAP packet data */
  934.     switch(hdr.code) {
  935.     case AUTH_REQ:                /* Request of remote host */
  936.         pap_rcvreq(sp, &hdr, bp);
  937.         break;
  938.     case AUTH_ACK:                /* Remote accepted our req */
  939.         pap_rcvack(sp, &hdr, bp);
  940.         break;
  941.     case AUTH_NAK:                /* Remote declined our req */
  942.         pap_rcvnak(sp, &hdr, bp);
  943.         break;
  944.     default:
  945.         if (ppptrace)
  946.             mainlog(-1,"%s: PPP/PAP: Unknown packet type: %x; dropping packet",
  947.                 sp->iface->name,hdr.code);
  948.         free_p(bp);
  949.         break;
  950.     }
  951.     return;
  952. }
  953.